/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty.  In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
// var b2Math = Class.create();
// b2Math.prototype =
import b2Vec2 from './b2Vec2';
import b2Mat22 from './b2Mat22';
export default class b2Math {
    constructor() { }
    /*static public function b2InvSqrt(x)
    {
        float32 xhalf = 0.5f * x;
        int32 i = *(int32*)&x;
        i = 0x5f3759df - (i >> 1);
        x = *(float32*)&i;
        x = x * (1.5f - xhalf * x * x);
        return x;
    }*/
    // A * B
    // A^T * B
    // b2Math.b2Random number in range [-1,1]
    /*inline float32 b2Math.b2Random(float32 lo, float32 hi)
    {
        float32 r = (float32)rand();
        r /= RAND_MAX;
        r = (hi - lo) * r + lo;
        return r;
    }*/
    // "Next Largest Power of 2
    // Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
    // that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
    // the same most significant 1, but all 1's below it. Adding 1 to that value yields the next
    // largest power of 2. For a 32-bit value:"
    // Temp vector functions to reduce calls to 'new'
    /*static public var tempVec = new b2Vec2();


    static public var tempAABB = new b2AABB();	*/
    static b2IsValid(x) {
        return isFinite(x);
    }
    static b2Dot(a, b) {
        return a.x * b.x + a.y * b.y;
    }
    static b2CrossVV(a, b) {
        return a.x * b.y - a.y * b.x;
    }
    static b2CrossVF(a, s) {
        var v = new b2Vec2(s * a.y, -s * a.x);
        return v;
    }
    static b2CrossFV(s, a) {
        var v = new b2Vec2(-s * a.y, s * a.x);
        return v;
    }
    static b2MulMV(A, v) {
        var u = new b2Vec2(A.col1.x * v.x + A.col2.x * v.y, A.col1.y * v.x + A.col2.y * v.y);
        return u;
    }
    static b2MulTMV(A, v) {
        var u = new b2Vec2(b2Math.b2Dot(v, A.col1), b2Math.b2Dot(v, A.col2));
        return u;
    }
    static AddVV(a, b) {
        var v = new b2Vec2(a.x + b.x, a.y + b.y);
        return v;
    }
    static SubtractVV(a, b) {
        var v = new b2Vec2(a.x - b.x, a.y - b.y);
        return v;
    }
    static MulFV(s, a) {
        var v = new b2Vec2(s * a.x, s * a.y);
        return v;
    }
    static AddMM(A, B) {
        var C = new b2Mat22(0, b2Math.AddVV(A.col1, B.col1), b2Math.AddVV(A.col2, B.col2));
        return C;
    }
    static b2MulMM(A, B) {
        var C = new b2Mat22(0, b2Math.b2MulMV(A, B.col1), b2Math.b2MulMV(A, B.col2));
        return C;
    }
    static b2MulTMM(A, B) {
        var c1 = new b2Vec2(b2Math.b2Dot(A.col1, B.col1), b2Math.b2Dot(A.col2, B.col1));
        var c2 = new b2Vec2(b2Math.b2Dot(A.col1, B.col2), b2Math.b2Dot(A.col2, B.col2));
        var C = new b2Mat22(0, c1, c2);
        return C;
    }
    static b2Abs(a) {
        return a > 0.0 ? a : -a;
    }
    static b2AbsV(a) {
        var b = new b2Vec2(b2Math.b2Abs(a.x), b2Math.b2Abs(a.y));
        return b;
    }
    static b2AbsM(A) {
        var B = new b2Mat22(0, b2Math.b2AbsV(A.col1), b2Math.b2AbsV(A.col2));
        return B;
    }
    static b2Min(a, b) {
        return a < b ? a : b;
    }
    static b2MinV(a, b) {
        var c = new b2Vec2(b2Math.b2Min(a.x, b.x), b2Math.b2Min(a.y, b.y));
        return c;
    }
    static b2Max(a, b) {
        return a > b ? a : b;
    }
    static b2MaxV(a, b) {
        var c = new b2Vec2(b2Math.b2Max(a.x, b.x), b2Math.b2Max(a.y, b.y));
        return c;
    }
    static b2Clamp(a, low, high) {
        return b2Math.b2Max(low, b2Math.b2Min(a, high));
    }
    static b2ClampV(a, low, high) {
        return b2Math.b2MaxV(low, b2Math.b2MinV(a, high));
    }
    static b2Swap(a, b) {
        var tmp = a[0];
        a[0] = b[0];
        b[0] = tmp;
    }
    static b2Random() {
        return Math.random() * 2 - 1;
    }
    static b2NextPowerOfTwo(x) {
        x |= (x >> 1) & 0x7FFFFFFF;
        x |= (x >> 2) & 0x3FFFFFFF;
        x |= (x >> 4) & 0x0FFFFFFF;
        x |= (x >> 8) & 0x00FFFFFF;
        x |= (x >> 16) & 0x0000FFFF;
        return x + 1;
    }
    static b2IsPowerOfTwo(x) {
        var result = x > 0 && (x & (x - 1)) == 0;
        return result;
    }
}
b2Math.tempVec2 = new b2Vec2();
b2Math.tempVec3 = new b2Vec2();
b2Math.tempVec4 = new b2Vec2();
b2Math.tempVec5 = new b2Vec2();
b2Math.tempMat = new b2Mat22();
